package cn.cyh.imeans.bat;

import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;

public class SelectScreenCompare {

    private int x = 0;
    private int y = 0;

    static {
        String basedir = System.getProperty("user.dir");
        Path libraryPath = Paths.get(basedir, "libs", "x64", "opencv_java3416.dll");
        System.load(libraryPath.toString());
    }

    public static void compare() throws Exception {
        // 创建Robot实例
        Robot robot = new Robot();

        int captureWidth = 30;
        int captureHeight = 30;
        Rectangle captureRect1 = new Rectangle(Test.POINT_MAP.get("x"), Test.POINT_MAP.get("y"), captureWidth, captureHeight);
        Rectangle captureRect2 = new Rectangle(Test.POINT_MAP.get("x")+10, Test.POINT_MAP.get("y")+10, captureWidth, captureHeight);
        // 捕获屏幕指定区域的图像
        BufferedImage screenCapture1 = robot.createScreenCapture(captureRect1);
        BufferedImage screenCapture2 = robot.createScreenCapture(captureRect2);
        String filePath1 = "C:\\Users\\DELL\\Desktop\\3.png";
        String filePath2 = "C:\\Users\\DELL\\Desktop\\4.png";
        ImageIO.write(screenCapture1, "png", new File(filePath1));
        System.err.println("保存图片3.png");
        ImageIO.write(screenCapture2, "png", new File(filePath2));
        System.err.println("保存图片4.png");

        /*Robot robot = new Robot();
        robot.setAutoDelay(1000);
        robot.mouseMove(1200, 575);
        robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
        robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
        robot.setAutoDelay(1000);
        robot.keyPress(KeyEvent.VK_ENTER);
        robot.keyRelease(KeyEvent.VK_ENTER);*/

        // 读取图像
        Mat src1 = Imgcodecs.imread("C:\\Users\\DELL\\Desktop\\3.png");
        Mat src2 = Imgcodecs.imread("C:\\Users\\DELL\\Desktop\\4.png");
        // 检查图片是否加载成功
        if (src1.empty() || src2.empty()) {
            System.err.println("无法加载图片");
            return;
        }
        // 调整图片尺寸
        int width = src1.width();
        int height = src1.height();
        resizeImage(src1, width, height);
        resizeImage(src2, width, height);
        // 计算直方图间的相似度
        double mse = calculateMSE(matToArray(src1), matToArray(src2));
        System.out.println("mse: " + mse);
        System.out.println("相同: " + (mse < 1000));
    }

    private static void resizeImage(Mat src, int width, int height) {
        Size size = new Size(width, height);
        Imgproc.resize(src, src, size);
    }

    private static int[][] matToArray(Mat mat) {
        Mat grayMat = new Mat();
        // 确保mat是一个灰度图像，如果是彩色图像，需要先转换为灰度
        if(mat.channels() > 1) {
            Imgproc.cvtColor(mat, grayMat, Imgproc.COLOR_BGR2GRAY);
        } else {
            grayMat = mat;
        }
        // 转换为二维数组
        int[][] array = new int[grayMat.rows()][grayMat.cols()];
        for (int i = 0; i < grayMat.rows(); i++) {
            for (int j = 0; j < grayMat.cols(); j++) {
                array[i][j] = (int) grayMat.get(i, j)[0]; // 获取单个像素值并转换为int类型
            }
        }
        return array;
    }

    /**
     * 计算两幅图像的均方误差（MSE）,MSE越小，说明两张图片越相似
     * @param image1 第一张图像的像素值矩阵
     * @param image2 第二张图像的像素值矩阵
     * @return 均方误差
     */
    private static double calculateMSE(int[][] image1, int[][] image2) {
        if (image1.length != image2.length || image1[0].length != image2[0].length) {
            throw new IllegalArgumentException("两幅图像尺寸不匹配");
        }

        int height = image1.length;
        int width = image1[0].length;
        double sum = 0.0;

        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                int diff = image1[i][j] - image2[i][j];
                sum += Math.pow(diff, 2);
            }
        }

        // 计算平均误差的平方
        double mse = sum / (height * width);
        return mse;
    }
}

